package com.zzl.admin.config.shiro;

import com.zzl.admin.entity.admin.Resource;
import com.zzl.admin.service.admin.ResourceService;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description：shiro配置类
 * Created by 朱正磊 on 2019-03-25 13:47
 */
@Configuration
@Import(ShiroManager.class)
public class ShiroConfig {

    @Autowired
    @SuppressWarnings("SpringAutowiredFieldsWarningInspection")
    private ResourceService resourceService;

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    @ConditionalOnMissingBean
    public Realm realm() {
        return new MyRealm();
    }

    /**
     * description：用户授权信息Cache
     * user 朱正磊
     * time 2019-03-30 13:02
     * @return 返回缓存管理器
     */
    @Bean(name = "shiroCacheManager")
    @ConditionalOnMissingBean
    public CacheManager cacheManager() {
        // TODO: 2019-03-30 shiro自带的MemoryConstrainedCacheManager作缓存只能用于本机，那么在集群时就无法使用
        return new MemoryConstrainedCacheManager();
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultSecurityManager securityManager() {
        DefaultSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setCacheManager(cacheManager());
        return securityManager;
    }

    @Bean
    @DependsOn("securityManager")
    @ConditionalOnMissingBean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager, Realm realm) {
        securityManager.setRealm(realm);
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        shiroFilter.setLoginUrl("/admin/login"); //去登录跳转地址
        shiroFilter.setSuccessUrl("/admin/index"); //登录成功跳转地址
        shiroFilter.setUnauthorizedUrl("/previlige/no"); //无权限跳转地址（没啥用）

        Map<String, String> filterChainDefinitionMap = new HashMap<>();
        filterChainDefinitionMap.put("/assets/**", "anon"); //静态资源文件放行不拦截
        filterChainDefinitionMap.put("/admin/login", "anon"); //去登录放行不拦截

        List<Resource> list = resourceService.findAll();
        for (Resource resource : list) {
            //添加增删查改权限
            filterChainDefinitionMap.put(resource.getSourceUrl(), "perms[" + resource.getSourceKey() + "]");
        }

        filterChainDefinitionMap.put("/admin/**", "authc"); // 拦截/admin/为前缀的地址
        shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilter;
    }

}
